#include "CHighScoreState.h"
#include "tinyxml/tinyxml.h"
#include "VIN_SoundManager.h"
#include "SGD Wrappers/CSGD_DirectInput.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "CMainMenuState.h"
#include "CHubState.h"
#include "CGame.h"
#include "VIN_BitMapFont.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include <algorithm>
#include <stdio.h>

using std::sort;

CHighScoreState::CHighScoreState()
{
	m_fBGM = 1.0f;
	LatestScore = charPos = 0;
	Achieve = false;

	filepath = "resource/XML/Highscores.xml";
	m_nBGI = CSGD_TextureManager::GetInstance()->LoadTexture("resource/Graphics/Rio.png");

	Load(filepath.c_str());
	if(Records.size() <= 0 )
	{
		for(int i = 0; i < 10; i++)
		{
			ScoreStruct* temp = new ScoreStruct();
			temp->name = "David Brown";
			temp->Score = 10;
			Records.push_back(temp);	
			//delete temp;
		}
	}
}

CHighScoreState::CHighScoreState(const CHighScoreState& copy)
{

}

CHighScoreState* CHighScoreState::GetInstance(void)
{
	static CHighScoreState instance;
	return &instance;
}

CHighScoreState::~CHighScoreState()
{

}

void CHighScoreState::Enter()
{
	VIN_SoundManager::GetInstance()->PlayBGM(BGM_HIGHSCORES);
	Load(filepath.c_str());
}

void CHighScoreState::Exit()
{
	VIN_SoundManager::GetInstance()->StopSound(BGM_HIGHSCORES);
	if(Records.size() > 0 )
	{
		Save(filepath.c_str());
	}
}

bool Sorta( ScoreStruct* obj1, ScoreStruct* obj2 )
{ 
	return obj1->Score > obj2->Score;
}

void CHighScoreState::Render()
{
	VIN_BitMapFont* pBF = VIN_BitMapFont::GetInstance();
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
	CSGD_Direct3D* pD3D = CSGD_Direct3D::GetInstance();

	if(Achieve)
	{
		if(Records.size() > 0 )
		{			
			pD3D->Clear();
			pD3D->DeviceBegin();
			pD3D->SpriteBegin();
			RECT MenuRect;
			SetRect( &MenuRect, 115, 115, 600, 400 );

			RECT MenuRectII;
			SetRect( &MenuRectII, 100, 100, 615, 415 );

			pD3D->GetSprite()->Flush();
			pD3D->DrawRect( MenuRectII, 255,255,255);
			pD3D->DrawRect( MenuRect, 0,0,0);
			pD3D->GetSprite()->Flush();

			//sort(Records.begin(), Records.end(), Sorta);
			pTM->Draw(m_nBGI,0,0);
			pBF->Render("YOU GOT A HIGH SCORE!!!!!", 100, 100, 1.5f, D3DCOLOR_ARGB(255,255,0,255), MENUFONT );
			pBF->Render("_________________", 100, 110, 1.5f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("Please Enter your name below: ", 35, 200, 1.25f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );

			pBF->Render(buffer, 100, 350, 1.0f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			
			pD3D->SpriteEnd();
			pD3D->DeviceEnd();
			pD3D->Present();
		}
	}
	else
	{
		if(Records.size() > 0 )
		{
			sort(Records.begin(), Records.end(), Sorta);
			pTM->Draw(m_nBGI,0,0);

			pBF->Render("HIGHSCORES", 300, 0, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("__________", 300, 5, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("Name", 30, 25, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("____", 30, 30, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("Score", 700, 25, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
			pBF->Render("_____", 700, 30, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );

			for(unsigned int i = 0; i < Records.size(); i++)
			{
				if(i < 10)
				{
					char Name[100];
					sprintf_s(Name, sizeof(Name), Records[i]->name.c_str());
					char Score[100];
					sprintf_s(Score, sizeof(Score), "%d", Records[i]->Score);

					pBF->Render(Name, 50, (i * 40) + 75, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
					pBF->Render(Score, 650, (i * 40) + 75, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
				}
			}

			pBF->Render("Press ESC to Exit. . . .", 200, 500, 0.75f, D3DCOLOR_ARGB(255,255,0,255), GAMEFONT );
		}
	}
}

void CHighScoreState::Update(float fElapsedTime)
{
	if(Achieve)
	{
		VIN_BitMapFont* pBF = VIN_BitMapFont::GetInstance();
		CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
		CSGD_DirectInput* pDI = CSGD_DirectInput::GetInstance();

		buffer[charPos] = '_';

		pressed = 0;
		if ((pressed = pDI->CheckBufferedKeysEx()) != 0)
		{
			if(pDI->CheckBufferedKeysEx() == 0x08)
			{
				if(charPos > 0)
				{
					//buffer[charPos] = '_';
					buffer[charPos - 1] = 0;
					buffer[charPos] = 0;
					charPos--;
				}
			}
			else
			{
				//buffer[charPos + 1] = '_';
				buffer[charPos] = pressed;
				charPos++;
			}
		}

		if(pDI->KeyPressed(DIK_RETURN))
		{
			buffer[charPos + 1] = NULL;
			ScoreStruct* temp = new ScoreStruct();
			temp->name = buffer;
			temp->Score = LatestScore;
			Records.push_back(temp);
			Achieve = false;
			//delete temp;
			for(int i = 0; i < sizeof(buffer); i++)
			{
				buffer[i] = 0;
			}
		}
	}
	else
	{
		charPos = 0;
		// Clear this buffer
		//buffer[100];
	}
}

bool CHighScoreState::Input()
{
	CSGD_DirectInput* pDI = CSGD_DirectInput::GetInstance();

	if( pDI->KeyPressed( DIK_ESCAPE ))
	{
		CGame::GetInstance()->ChangeState( CMainMenuState::GetInstance() );
	}

	return true;
}
bool CHighScoreState::Load(const char* filename)
{
	TiXmlDocument doc;

	if(doc.LoadFile(filename) == false)
		return false;

	TiXmlElement* pRoot = doc.RootElement();

	if(pRoot == NULL)
		return false;

	TiXmlElement* Highscore = pRoot->FirstChildElement("Highscore");

	//for(unsigned int i = 0; i < Records.size(); i++)
	//{
	//	delete Records[i];
	//}
	Records.clear();

	while(Highscore)
	{
		ScoreStruct* temp = new ScoreStruct();

		Highscore->Attribute("score", &temp->Score);

		temp->name = Highscore->Attribute("name");

		Records.push_back(temp);
		
		Highscore = Highscore->NextSiblingElement();
		
		//delete temp;
	}

	return true;
}
bool CHighScoreState::Save(const char* filename)
{
	TiXmlDocument doc;

	TiXmlDeclaration* pDec = new TiXmlDeclaration("1.0", "utf-8", "");

	// 1. Cut a hole in the box
	// 2. Put your dec in the box
	doc.LinkEndChild(pDec);


	TiXmlElement* pRoot = new TiXmlElement("highscores");

	doc.LinkEndChild(pRoot);

	for(int i = 0; i < 10; i++)
	{
		TiXmlElement* pHighScore = new TiXmlElement("Highscore");

		pHighScore->SetAttribute("score", Records[i]->Score);

		pHighScore->SetAttribute("name", Records[i]->name.c_str());

		// put highscore in highscores
		pRoot->LinkEndChild(pHighScore);
	}

	if(doc.SaveFile(filename) == false)
		return false;

	return true;
}

void CHighScoreState::Achievement( bool Trigger, int Score )
{
	Achieve = Trigger;
	LatestScore = Score;
}
